package com.pay.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayConstants;
import com.alipay.api.internal.util.AlipaySignature;
import com.pay.entity.OrderInfo;
import com.pay.service.AliPayService;
import com.pay.service.OrderInfoService;
import com.pay.vo.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Map;

/**
 * @author Administrator
 * @create 2022-06-23 17:50
 */
@Slf4j
@CrossOrigin
@RestController
@RequestMapping("/api/ali-pay")
@Api(tags = "网站支付宝支付")
public class AliPayController {

    @Resource
    private AliPayService aliPayService;

    @Resource
    private Environment config;

    @Resource
    private OrderInfoService orderInfoService;


    @ApiOperation("统一收单下单并支付页面的调用")
    @PostMapping("/trade/page/pay/{productId}")
    public R tradePagePay(@PathVariable Long productId){
        log.info("统一收单下单并支付页面的调用");
        //支付宝开放平台接受request对象后 会为开发者生成一个html形式的form表单，包含自动提交的脚本
        String formStr =  aliPayService.tradeCreate(productId);
        //我们将form表单字符串返回给前端程序，之后前端将会调用自动提交的脚本，进行表单的提交
        //此时，表单后自动提交到action属性指向的支付宝开放平台中，从而为用户展示一个支付页面
        return R.ok().data("formStr",formStr);
    }

    @ApiOperation("支付通知")
    @PostMapping("/trade/notify")
    public String tradeNotify(@RequestParam Map<String,String> params){
        log.info("支付通知正在执行");
        log.info("通知参数 ===>{}",params);

        String result = "failure";

        try {
            //异步通知验签
            boolean signVerified = AlipaySignature.rsaCheckV1(
                    params,
                    config.getProperty("alipay.alipay-public-key"),
                    AlipayConstants.CHARSET_UTF8,
                    AlipayConstants.SIGN_TYPE_RSA2); //调用SDK验证签名

            if(!signVerified){
                // 验签失败则记录异常日志，并在response中返回failure.
                log.error("支付成功异步通知验签失败");
                return result;
            }

            //验签成功后，按照支付结果异步通知中的描述，对支付结果中的业务内容进行二次校验
            log.info("支付成功异步通知验签成功");

            //校验成功后在response中返回success并继续商户自身业务处理
            String outTradeNo = params.get("out_trade_no");
            OrderInfo order = orderInfoService.getOrderByOrderNo(outTradeNo);
            if (order == null){
                log.error("支付成功异步通知，订单不存在");
                return result;
            }

            String totalAmount = params.get("total_amount");
            int totalAmountInt = new BigDecimal(totalAmount).multiply(new BigDecimal("100")).intValue();
            int intValue = order.getTotalFee().intValue();
            if (totalAmountInt != intValue){
                log.error("支付成功异步通知，订单金额不一致");
                return result;
            }

            String sellerId = params.get("seller_id");
            if (!sellerId.equals(config.getProperty("alipay.seller-id"))){
                log.error("支付成功异步通知，商户id不一致");
                return result;
            }

            String appId = params.get("app_id");
            if (!appId.equals(config.getProperty("alipay.app-id"))){
                log.error("支付成功异步通知，appid不一致");
                return result;
            }

            String tradeStatus = params.get("trade_status");
            if (!tradeStatus.equals("TRADE_SUCCESS")){
                log.error("支付成功异步通知，支付状态不是支付成功");
                return result;
            }

            aliPayService.processOrder(params);


            //向支付宝返回成功的返回
            result = "success";
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return result;
    }

    @ApiOperation("用户取消订单")
    @PostMapping("/trade/close/{orderNo}")
    public R cancel(@PathVariable String orderNo){
        log.info("取消订单");
        aliPayService.cancelOrder(orderNo);
        return R.ok().setMessage("订单已取消");
    }

    @ApiOperation("查单接口")
    @GetMapping("/trade/query/{orderNo}")
    public R queryOrder(@PathVariable String orderNo) {
        log.info("向支付宝查询订单");
        String result =  aliPayService.queryOrder(orderNo);
        return R.ok().setMessage("查询成功").data("result",result);
    }

    /**
     * 申请退款
     * @param orderNo
     * @param reason
     * @return
     */
    @ApiOperation("申请退款")
    @PostMapping("/trade/refund/{orderNo}/{reason}")
    public R refunds(@PathVariable String orderNo, @PathVariable String reason){
        log.info("申请退款");
        aliPayService.refund(orderNo, reason);
        return R.ok();
    }

    /**
     * 查询退款
     * @param orderNo
     * @return
     * @throws Exception
     */
    @ApiOperation("查询退款：测试用")
    @GetMapping("/trade/fastpay/refund/{orderNo}")
    public R queryRefund(@PathVariable String orderNo) throws Exception {
        log.info("查询退款");
        String result = aliPayService.queryRefund(orderNo);
        return R.ok().setMessage("查询成功").data("result", result);
    }

    /**
     * 根据账单类型和日期获取账单url地址
     *
     * @param billDate
     * @param type
     * @return
     */
    @ApiOperation("获取账单url")
    @GetMapping("/bill/downloadurl/query/{billDate}/{type}")
    public R queryTradeBill(
            @PathVariable String billDate,
            @PathVariable String type)  {
        log.info("获取账单url");
        String downloadUrl = aliPayService.queryBill(billDate, type);
        return R.ok().setMessage("获取账单url成功").data("downloadUrl", downloadUrl);
    }
}